package com.rongcheng.frc.androidlib.net;

import android.content.res.AssetManager;
import android.content.res.Resources;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.rongcheng.frc.androidlib.activity.BaseActivity;
import com.rongcheng.frc.androidlib.net.mock.MockConfigManager;
import com.rongcheng.frc.androidlib.net.mock.MockSettingData;
import com.rongcheng.frc.androidlib.net.mock.YXResponse;
import com.rongcheng.frc.androidlib.net.requestCallback.YXBaseCallBack;
import com.rongcheng.frc.androidlib.net.requestCallback.YXFileCallBack;
import com.zhy.http.okhttp.OkHttpUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Random;

import static com.rongcheng.frc.androidlib.net.UrlConfigManager.findURL;

/**
 * Created by FengRongCheng on 2016/6/18 16:54.
 * powered by yanxiu.com
 */
public class YXNetWorkManager {

    public static YXNetWorkManager getInstance() {
        return YXNetWorkManagerHolder.instance;
    }

    private static class YXNetWorkManagerHolder {
        private final static YXNetWorkManager instance = new YXNetWorkManager();
    }

    public void invoke(final BaseActivity activity,
                       final String apiKey,
                       final Map<String, String> params,
                       final YXBaseCallBack callBack) {
        final URLData urlData = findURL(activity, apiKey);
        /**先判断整个app的网络框架是否为模拟状况**/
        Log.e("frc", "isLinkedService: :" + UrlConfigManager.isLinkedService);
        if (!UrlConfigManager.isLinkedService) {
            Log.e("frc", "isUseMockData: :" + urlData.isUseMockData());
            if (urlData.isUseMockData()) {//判断当前接口是否为模拟
                final MockSettingData mockSettingData = MockConfigManager.findMockConfig(activity, apiKey);
                String ClassName = urlData.getMockClass();
                if (ClassName != null) {
                    try {
                        //TODO 需要优化 异步
                        Thread.sleep(new Random().nextInt(Integer.valueOf(UrlConfigManager.ConnctedTime)) * 1000);
                        String strResponse = getRandomResponse(activity, mockSettingData);
                        final YXResponse responseInJson = JSON.parseObject(strResponse,
                                YXResponse.class);
                        switch (responseInJson.getCode()) {
                            case "0":
                                callBack.onSuccess(strResponse, true);
                                break;
                            case "1":
                            case "2":
                                callBack.onFail(strResponse, true);
                                break;
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            } else {
                Log.e("frc", "用真实网络");
            }
        } else {
            Log.e("frc", "用真实网络");
            if (urlData.getNetType().equals("get"))
                OkHttpUtils.getInstance().get().url(urlData.getUrl()).params(params).tag(apiKey).build().execute(callBack);
            else if (urlData.getNetType().equals("post"))
                OkHttpUtils.getInstance().post().url(urlData.getUrl()).params(params).tag(apiKey).build().execute(callBack);

        }


    }

    /**
     * 上传多个文件
     *
     * @param activity
     * @param apiKey
     * @param fileKey
     * @param params
     * @param callBack
     */
    public void UploadFiles(final BaseActivity activity,
                            final String apiKey,
                            final String fileKey,
                            final Map<String, File> params,
                            final YXBaseCallBack callBack) {

        final URLData urlData = findURL(activity, apiKey);
        OkHttpUtils.getInstance().post().url(urlData.getUrl()).files(fileKey, params).tag(apiKey).build().execute(callBack);
    }

    /**
     * 直接post单个文件
     *
     * @param activity
     * @param apiKey
     * @param file
     * @param callBack
     */
    public void PostFile(final BaseActivity activity,
                         final String apiKey,
                         final File file,
                         final YXBaseCallBack callBack) {
        final URLData urlData = findURL(activity, apiKey);

        try {
            OkHttpUtils.getInstance().postFile().url(urlData.getUrl()).file(file).tag(apiKey).build().execute();
        } catch (IOException e) {
            e.printStackTrace();
            callBack.onFail(e.getMessage(), false);
        }
    }

    /**
     * post字符串
     *
     * @param activity
     * @param apiKey
     * @param strContent
     * @param callBack
     */
    public void PostString(final BaseActivity activity,
                           final String apiKey,
                           final String strContent,
                           final YXBaseCallBack callBack) {
        final URLData urlData = findURL(activity, apiKey);

        try {
            OkHttpUtils.getInstance().postString().url(urlData.getUrl()).content(strContent).tag(apiKey).build().execute();
        } catch (IOException e) {
            e.printStackTrace();
            callBack.onFail(e.getMessage(), false);
        }
    }

    /**
     * 下载文件 并有对应的进度
     *
     * @param activity
     * @param apiKey
     * @param callBack
     */
    public void DownLoadFile(final BaseActivity activity,
                             final String apiKey, YXFileCallBack callBack) {
        final URLData urlData = findURL(activity, apiKey);
        OkHttpUtils.getInstance().get().url(urlData.getUrl()).tag(apiKey).build().execute(callBack);
    }

    /**
     * 根据设置的概率值获取返回数据
     *
     * @param mockSettingData
     */
    private String getRandomResponse(BaseActivity activity, MockSettingData mockSettingData) {
        Resources res = activity.getResources();
        AssetManager assetManager = activity.getAssets();
        Random random = new Random();
        String responseString = "";
        int tryTimes = mockSettingData.getErrorScale() + mockSettingData.getSuccessScale() + mockSettingData.getNetErrorScale();
        int randomCount = random.nextInt(tryTimes);

        if (randomCount < mockSettingData.getErrorScale() && randomCount >= 0) {
            responseString = getFailResponse(assetManager);

        } else if (randomCount < mockSettingData.getErrorScale() + mockSettingData.getSuccessScale() && randomCount >= mockSettingData.getErrorScale()) {
            responseString = getSuccessResponse(assetManager, mockSettingData);

        } else {

            responseString = getNetErrorResponse(assetManager);
        }

        return responseString;

    }

    private String getSuccessResponse(AssetManager assetManager, MockSettingData mockSettingData) {
        return getAssetsResourceToStr(mockSettingData.getMockFile(), assetManager);
    }

    private String getFailResponse(AssetManager assetManager) {
        return getAssetsResourceToStr("error_data_response", assetManager);
    }

    private String getNetErrorResponse(AssetManager assetManager) {
        return getAssetsResourceToStr("net_error_response", assetManager);
    }

    private String getAssetsResourceToStr(String fileName, AssetManager assetManager) {
        String responseString = "";
        try {
            InputStream inputStream = assetManager.open(fileName);
            int length = inputStream.available();
            byte[] buffer = new byte[length];
            inputStream.read(buffer);
            responseString = new String(buffer, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }

        Log.e("frc", responseString);
        return responseString;
    }

    public void CancelRequestByTag(String Tag) {
        OkHttpUtils.getInstance().cancelTag(Tag);
    }
}
